////////////////////////////////////////////////////////////////////////////////////////////////////
/// Copyright (c) 2009 - 2010 RacoonStudios
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this
/// software and associated documentation files (the "Software"), to deal in the Software
/// without restriction, including without limitation the rights to use, copy, modify, merge,
/// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
/// to whom the Software is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all copies or
/// substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
/// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
/// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
/// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
/// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// DEALINGS IN THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once
#ifndef xmlwriter_h__
#define xmlwriter_h__

#include "iosystem/streamwriter.h"
#include "ticpp/ticpp.h"

namespace IO
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \class	XmlWriter
	///
	/// \brief	This class provides a simple interface for writing xml data to a stream.
	///			We don't do this directly we are using TiCPP for writing to XML files.
	///			This is just a nice little library which wraps C++ functionality around 
	///			the C'ish TiXML library.
	///			So you can open a new file stream for creating a new file and write some
	///			lines of xml valid code to it. You can write normal text within the opening
	///			and ending tag, add as many attributes to one tag as you want and of what
	///			data type you want. For now the XmlWriter will support directly matrix44, 
	///			float4, float2, String, bool, int and float.
	///			For know that enough, later on I will include more functionality to the
	///			String class so that this XmlWriter class can support writing more different
	///			types. There are still missing a lot of types, just to name some if them:
	///			quaternions, planes, lines, rectangles, vectors, spheres and boundingboxes.
	///
	///	\todo	I could also add some functions for writing some other important types
	///			to xml files, like quaternionen, vector2/3/4, planes, rectangles, spheres,
	///			line2/3, point2/4 ...
	///
	/// \author	khaos
	/// \date	05.01.2010
	////////////////////////////////////////////////////////////////////////////////////////////////////
	class XmlWriter : public IO::StreamWriter
	{
		RE_DeclareClass(IO::XmlWriter);

	public:

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	public: XmlWriter()
		///
		/// \brief	Constructor. 
		///
		/// \author	khaos
		/// \date	05.01.2010
		////////////////////////////////////////////////////////////////////////////////////////////////////
		XmlWriter();

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	virtual ~XmlWriter()
		///
		/// \brief	Finaliser. 
		///
		/// \author	khaos
		/// \date	05.01.2010
		////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual ~XmlWriter();




		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	virtual bool Open()
		///
		/// \brief	Opens stream for writing.
		///
		/// \author	khaos
		/// \date	05.01.2010
		///
		/// \return	True is stream was opened successfully, otherwise false.
		////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual bool Open();

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	virtual void Close()
		///
		/// \brief	Closes stream for writing.
		///
		/// \author	khaos
		/// \date	05.01.2010
		////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual void Close();




		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	bool BeginNode(const Helper::String & node)
		///
		/// \brief	Begins a new node under the current one.
		///
		/// \author	khaos
		/// \date	05.01.2010
		///
		/// \param	[in]	node	The node. 
		///
		/// \return	True if ne node was successfully created, otherwise false.
		////////////////////////////////////////////////////////////////////////////////////////////////////
		bool BeginNode(const Helper::String & node);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void EndNode()
		///
		/// \brief	Ends the current node.
		///
		/// \author	khaos
		/// \date	05.01.2010
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void EndNode();

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void WriteContent(const Helper::String & text)
		///
		/// \brief	Writes a containing text. 
		///
		/// \author	khaos
		/// \date	05.01.2010
		///
		/// \param	[in]	text	The text. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void WriteContent(const Helper::String & text);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void WriteComment(const Helper::String & text)
		///
		/// \brief	Writes a comment. 
		///
		/// \author	khaos
		/// \date	05.01.2010
		///
		/// \param	[in]	text	The text. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void WriteComment(const Helper::String & text);




		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void SetString(const Helper::String & name, const Helper::String & val)
		///
		/// \brief	Adds a String to the xml file. 
		///
		/// \author	khaos
		/// \date	13.01.2010
		///
		/// \param	[in]	name	The name of the attribute. 
		/// \param	[in]	val		The attributes value. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void SetString(const Helper::String & name, const Helper::String & val);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void SetBool(const Helper::String & name, bool val)
		///
		/// \brief	Adds a bool to the xml file. 
		///
		/// \author	khaos
		/// \date	13.01.2010
		///
		/// \param	[in]	name	The name of the attribute. 
		/// \param	[in]	val		The attributes value. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void SetBool(const Helper::String & name, bool val);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void SetInt(const Helper::String & name, int val)
		///
		/// \brief	Adds an int to the xml file. 
		///
		/// \author	khaos
		/// \date	13.01.2010
		///
		/// \param	[in]	name	The name of the attribute. 
		/// \param	[in]	val		The attributes value. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void SetInt(const Helper::String & name, int val);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void SetFloat(const Helper::String & name, float val)
		///
		/// \brief	Adds a float to the xml file. 
		///
		/// \author	khaos
		/// \date	13.01.2010
		///
		/// \param	[in]	name	The name of the attribute. 
		/// \param	[in]	val		The attributes value. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void SetFloat(const Helper::String & name, float val);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void SetFloat2(const Helper::String & name, const Math::float2 & val)
		///
		/// \brief	Adds a float2 to the xml file. 
		///
		/// \author	khaos
		/// \date	13.01.2010
		///
		/// \param	[in]	name	The name of the attribute. 
		/// \param	[in]	val		The attributes value. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void SetFloat2(const Helper::String & name, const Math::float2 & val);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void SetFloat4(const Helper::String & name, const Math::float4 & val)
		///
		/// \brief	Adds a float4 to the xml file. 
		///
		/// \author	khaos
		/// \date	13.01.2010
		///
		/// \param	[in]	name	The name of the attribute. 
		/// \param	[in]	val		The attributes value. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void SetFloat4(const Helper::String & name, const Math::float4 & val);

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// \fn	void SetMatrix(const Helper::String & name, const Math::matrix & val)
		///
		/// \brief	Adds a matrix to the xml file. 
		///
		/// \author	khaos
		/// \date	13.01.2010
		///
		/// \param	[in]	name	The name of the attribute. 
		/// \param	[in]	val		The attributes value. 
		////////////////////////////////////////////////////////////////////////////////////////////////////
		void SetMatrix(const Helper::String & name, const Math::matrix & val);

	protected:

	private:

		ticpp::Document *		m_xmlDoc;
		ticpp::Element *		m_curNode;

	};

}

#endif // xmlwriter_h__